package feeinterface.protocol.business;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.ulwx.tool.RandomUtils;
import com.ulwx.tool.StringUtils;

import feeinterface.dao.BaseClientSmsCloseDao;
import feeinterface.dao.BaseDynamicRegularDao;
import feeinterface.dao.ChannelProvinceMtCloseTimeLenDao;
import feeinterface.dao.ChannelTestDao;
import feeinterface.dao.ServiceClassProvinceDao;
import feeinterface.model.ChannelInfo;
import feeinterface.modeldb.BaseClientSmsClose;
import feeinterface.modeldb.BaseDynamicRegular;
import feeinterface.modeldb.Channel;
import feeinterface.modeldb.ChannelIvr;
import feeinterface.modeldb.ChannelSms;
import feeinterface.modeldb.ChannelTest;
import feeinterface.modeldb.ChannelWap;
import feeinterface.modeldb.ServiceClassProvince;
import feeinterface.modeldb.ServiceCo;
import feeinterface.protocol.res.ChannelIVR;
import feeinterface.protocol.res.ChannelSMS;
import feeinterface.protocol.res.ChannelWAP;
import feeinterface.protocol.res.CmdAddr;
import feeinterface.protocol.res.Res010001;
import feeinterface.protocol.utils.Constants;
import feeinterface.protocol.utils.Constants.ChannelBigType;

/**
 * 计费通用接口
 * 
 * @author 黄杰
 * 
 */

public class FeeUtil {

	private static final Logger log = Logger.getLogger(FeeUtil.class);

	/**
	 * 获取通道失败
	 * 
	 * @param FeeStatus
	 * @return 
	 */
	public static Res010001 getFail(int feeStatus) {
		Res010001 res = new Res010001();
		res.Protocol = "010001";
		res.Status = Constants.Status.FAIL;
		res.Message = Constants.getFeeStatus(feeStatus);
		;
		res.FeeID = "";
		res.ThisFee = 0;
		res.FeeStatus = feeStatus;
		res.SmsCloseMt = Constants.CloseMt.NoNeedCloseMt;
		res.SmsCloseTime = 0;
		res.SmsCloseSpNumber = "";
		res.SmsOpenSpNumber = "";
		res.SmsCloseKeyword = "";
		res.ExtRespVar = "";
		return res;
	}

	/**
	 * 获取默认值
	 * 
	 * @param FeeStatus
	 * @return
	 */
	public static Res010001 getDefault(int FeeStatus) {
		Res010001 res = new Res010001();
		res.Protocol = "010001";
		res.Status = Constants.Status.SUCCESS;
		res.Message = Constants.getFeeStatus(FeeStatus);
		res.FeeID = "";
		res.ThisFee = 0;
		res.FeeStatus = FeeStatus;
		res.SmsCloseMt = Constants.CloseMt.NoNeedCloseMt;
		res.SmsCloseTime = 0;
		res.SmsCloseSpNumber = "";
		res.SmsOpenSpNumber = "";
		res.SmsCloseKeyword = "";
		res.ExtRespVar = "";
		log.info(res.Message);
		return res;
	}

	/**
	 * 获取默认值
	 * 
	 * @param FeeStatus
	 * @return
	 */
	public static Res010001 getDefault(int FeeStatus, String extInfo) {
		Res010001 res = new Res010001();
		res.Protocol = "010001";
		res.Status = Constants.Status.SUCCESS;
		res.Message = Constants.getFeeStatus(FeeStatus) + "[" + extInfo + "]";
		res.FeeID = "";
		res.ThisFee = 0;
		res.FeeStatus = FeeStatus;
		res.SmsCloseMt = Constants.CloseMt.NoNeedCloseMt;
		res.SmsCloseTime = 0;
		res.SmsCloseSpNumber = "";
		res.SmsOpenSpNumber = "";
		res.SmsCloseKeyword = "";
		res.ExtRespVar = "";
		log.info(res.Message);
		return res;
	}

	/**
	 * 
	 * @param finalSelectChannels
	 * @param realFee
	 * @param provinceID
	 * @param service
	 * @param PhoneFactoryName
	 * @return
	 */
	public static Res010001 getQuery(List<ChannelInfo> finalSelectChannels,
			int realFee, int provinceID, ServiceCo service,
			String PhoneFactoryName, String carrier) {
		Res010001 res = new Res010001();
		try {
			res.Protocol = "010001";
			res.Status = Constants.Status.SUCCESS;
			res.Message = "成功";
			res.FeeStatus = Constants.FeeStatus.SuccussReturnChannel;// 正常范围通道
			res.FeeID = RandomUtils.genUUID();
			res.ThisFee = realFee;// 本次扣费实际扣的钱（分）
			List<ChannelSMS> smslist = new ArrayList<ChannelSMS>();
			List<ChannelWAP> waplist = new ArrayList<ChannelWAP>();
			List<ChannelIVR> ivrlist = new ArrayList<ChannelIVR>();
			int channelUseCnt = 0;
			for (int i = 0; i < finalSelectChannels.size(); i++) {
				ChannelInfo cinfo = finalSelectChannels.get(i);
				Channel ch = cinfo.getChannel();
				int sendCnt = cinfo.getSendCnt();// 次数
				channelUseCnt = channelUseCnt + sendCnt;
				Object chex = cinfo.getChanelExtInfo();
				if (ch.getChannelBigType() == Constants.ChannelBigType.SMS) {
					ChannelSms chsms = (ChannelSms) chex;
					// 解析短彩类通道，进行拼装！
					BaseDynamicRegular bsreg = null;
					CmdAddr[] ca = ParseFetch.parse(ch.getSendCmd(),
							ch.getDestAddr(), sendCnt,
							chsms.getSmsExtCmdAddrList());
					for (int j = 0; j < ca.length; j++) {
						ChannelSMS sms = new ChannelSMS();
						sms.ChannelID = ch.getChannelSno();
						sms.IsDouble = chsms.getDoublePrecision();
						if (sms.IsDouble == Constants.DoublePrecision.NO) {
							// 如果是模糊通道则加入COID
							sms.SmsFeeCmd = ca[j].Cmd
									+ service.getServiceCoSno();
							// ChSmsLen（模糊指令的最大长度）
							sms.ExtSmsVar = "ChSmsLen=" + chsms.getSmsLen();
						} else {
							sms.SmsFeeCmd = ca[j].Cmd;// 双精通道
						}

						if (StringUtils.hasText(sms.ExtSmsVar)) {
							sms.ExtSmsVar = sms.ExtSmsVar + "@@"
									+ ca[j].extSmsVar;
						} else {
							sms.ExtSmsVar = ca[j].extSmsVar;
						}
						sms.FeeTipInfo = ch.getFeeTipInfo();
						sms.FeeType = ch.getChannelTypeCode();
						// 如果长度为1，说明不是双短信通道,则发送次数根据计算所得;1065双短信通道,发送次数为1
						sms.SendCnt = ca.length == 1 ? sendCnt : 1;
						sms.SendInterval = ch.getClientSendInterval();
						sms.SmsFeeCode = ch.getFeeCode();
						sms.SmsFeePort = ca[j].Addr;
						int validateFlag = chsms.getValidateFlag();
						sms.SmsValidateFlag = (byte) validateFlag;
						if (validateFlag == Constants.ValidateSmsType.NeedClientValidate
								|| validateFlag == Constants.ValidateSmsType.NeedServerValidate) {
							bsreg = BaseDynamicRegularDao.getDyRegularBy(
									provinceID, ch.getChannelSno(), carrier)
									.get(0);
							;
							if (bsreg != null) {
								sms.SmsStartFlag = StringUtils.trim(bsreg
										.getStartFlag());
								sms.SmsEndFlag = StringUtils.trim(bsreg
										.getEndFlag());
							} else {
								sms.SmsStartFlag = "";
								sms.SmsEndFlag = "";
							}
						} else {
							sms.SmsValidateFlag = (byte) Constants.ValidateSmsType.NoNeedValidate;
							sms.SmsStartFlag = "";
							sms.SmsEndFlag = "";
						}
						smslist.add(sms);
					}
				} else if (ch.getChannelBigType() == Constants.ChannelBigType.WAP) {
					ChannelWAP wap = new ChannelWAP();
					ChannelWap chwap = (ChannelWap) chex;
					wap.ChannelID = ch.getChannelSno();
					wap.ExtWapVar = "";
					wap.FeeOKFlag = chwap.getFeeOKFlagList();
					wap.FeeTipInfo = ch.getFeeTipInfo();
					wap.FeeType = ch.getChannelTypeCode();
					wap.SendCnt = sendCnt;
					wap.SendInterval = ch.getClientSendInterval();
					wap.ValidateStep = chwap.getValidateStep().byteValue();
					if (wap.ValidateStep == Constants.ValidateWapType.NoNeedValidate) {
						wap.ValidateEndKey = "";
						wap.ValidateFindKeys = "";
					} else if (wap.ValidateStep == Constants.ValidateWapType.NeedClientPicValidate) {
						wap.ValidateEndKey = chwap.getValidateEndKey();
						wap.ValidateFindKeys = chwap.getValidateFindKeyList();
					} else {
						wap.ValidateStep = (byte) Constants.ValidateWapType.NoNeedValidate;
						wap.ValidateEndKey = "";
						wap.ValidateFindKeys = "";
					}
					wap.WapFeeUrl = ch.getDestAddr();
					wap.FeeStep = ParseFetch.analyse(chwap.getWAPFetchStrs());
					waplist.add(wap);
				} else if (ch.getChannelBigType() == Constants.ChannelBigType.IVR) {
					ChannelIvr chivr = (ChannelIvr) chex;
					// sendCnt为同一条IVR通道可以拨打IVR的次数，要转换成协议响应里的多次拨打
					for (int n = 0; n < sendCnt; n++) {
						ChannelIVR ivr = new ChannelIVR();
						ivr.ChannelID = ch.getChannelSno();
						ivr.ExtIvrVar = "";
						ivr.FeeTipInfo = ch.getFeeTipInfo();
						ivr.FeeType = ch.getChannelTypeCode();
						ivr.IvrFeeTel = ch.getDestAddr();
						ivr.KeySeries = chivr.getKeySeries();
						// ,算法：最短有效计费时长+Rnd*10+开始计费时长,单次拨打时长不超过一分钟，收取更多费用时使用多次拨打方式.
						ivr.SendCnt = chivr.getFeeMinTimeLen()
								+ RandomUtils.nextInt(10)
								+ chivr.getStartFeeTimeLen(); // 计算发送时长
						ivr.SendInterval = ch.getClientSendInterval()
								+ RandomUtils.nextInt(10);
						ivrlist.add(ivr);
					}
				} else {
				}
			}
			// 三种通道指令
			res.wap = waplist.toArray(new ChannelWAP[0]);
			res.sms = smslist.toArray(new ChannelSMS[0]);
			res.ivr = ivrlist.toArray(new ChannelIVR[0]);
			res.SmsCloseMt = service.getIsClostMt().byteValue();
			// 30 构造屏蔽信息
			if (service.getIsClostMt() == Constants.CloseMt.NeedClostMt) {
				// ========查找屏蔽信息
				BaseClientSmsClose closeInfo = BaseClientSmsCloseDao
						.getClientSmsCloseInfoBy(provinceID, PhoneFactoryName);
				res.SmsCloseTime = ChannelProvinceMtCloseTimeLenDao
						.getMtCloseTimeLenBy(provinceID);
				if (null != closeInfo) {
					res.SmsCloseKeyword = closeInfo.getCloseKeys();
					res.SmsCloseSpNumber = closeInfo.getCloseChannelPrefixs();
					res.SmsOpenSpNumber = closeInfo.getOpenChannelPrefixs();
				}
			} else if (service.getIsClostMt() == Constants.CloseMt.NoNeedCloseMt) {
				res.SmsCloseTime = 0;
			} else {
				res.SmsCloseMt = (byte) Constants.CloseMt.NoNeedCloseMt;
				res.SmsCloseTime = 0;
			}
		} catch (Exception e) {
			return res = FeeUtil
					.getDefault(Constants.FeeStatus.UnknownError_1001);
		}
		return res;
	}

	public static boolean decideByProvinceServiceClassCode(int provinceid,
			Integer serviceCode) throws Exception {
		if (serviceCode != null && serviceCode > 0) {

			List<ServiceClassProvince> splist = ServiceClassProvinceDao
					.getBy(provinceid);
			if (splist.size() > 0) {// 说明此省份进行了配置，只能走在配置里的合作ID
				// 判断当前的合作级别是否在配置里,如果在配置里，则进行扣费，否则不能扣费
				boolean pass = false;
				for (int i = 0; i < splist.size(); i++) {
					ServiceClassProvince sc = splist.get(i);
					if (sc.getServiceClassCode().intValue() == serviceCode
							.intValue()) {
						pass = true;
						break;
					}
				}

				if (!pass) {// 不能扣费
					return false;
				}
			} else {
				// 没有进行配置走正常流程
				return true;
			}

		}
		return true;
	}

	/**
	 * 根据imsi，pone，coid查找绑定测试的信息，如果有就返回
	 * 
	 * @param imsi
	 * @param phone
	 * @param coid
	 * @return
	 */
	public static Res010001 getBindTest(String imsi, String phone, Integer coid) {

		List<ChannelTest> list = null;
		try {
			list = ChannelTestDao.getTestDataBy(imsi, phone, coid);
		} catch (Exception ex) {
			log.error("", ex);
			return null;
		}
		if (list == null || list.size() < 0) {// 说明没有测试绑定，返回空
			return null;
		}
		ChannelSMS sms = null;
		ChannelWAP wap = null;
		ChannelIVR ivr = null;

		List<ChannelSMS> smsList = new ArrayList<ChannelSMS>();
		List<ChannelWAP> wapList = new ArrayList<ChannelWAP>();
		List<ChannelIVR> ivrList = new ArrayList<ChannelIVR>();
		// 开始拼装绑定测试资源
		Res010001 res = new Res010001();
		res.Protocol = "010001";
		res.Status = Constants.Status.SUCCESS;
		res.Message = "成功";
		res.FeeStatus = Constants.FeeStatus.BindTest;
		res.FeeID = RandomUtils.genUUID();

		ChannelTest smsCloseCt = null;
		int realFee = 0;
		int ChannelIDForTest = Constants.Channel.ChannelIdForTest;
		for (ChannelTest ct : list) {
			Integer channelID = ct.getChannelID();
			if (null == channelID || 0 == channelID) {
				channelID = ChannelIDForTest++;
			}

			if (ct.getFeeBigType() == ChannelBigType.SMS) {
				// SMS或MMS类
				if (ct.getEnable() == 0) {
					continue;
				}
				sms = new ChannelSMS();
				sms.FeeType = ct.getSMSFeeType();
				sms.ChannelID = channelID;
				sms.IsDouble = ct.getSMSSmsIsDouble();
				if (sms.IsDouble == Constants.DoublePrecision.NO) {
					sms.SmsFeeCmd = ct.getSMSSmsFeeCmd() + coid;
				} else {
					sms.SmsFeeCmd = ct.getSMSSmsFeeCmd();
				}
				sms.SmsFeePort = ct.getSMSSmsFeePort();
				sms.FeeTipInfo = ct.getSMSFeeTipInfo();
				try {
					sms.SmsFeeCode = Integer.parseInt(ct.getSMSSmsFeeCode());
				} catch (Exception e) {
					sms.SmsFeeCode = 0;
				}
				sms.SendCnt = ct.getSMSSendCnt();
				sms.SendInterval = ct.getSMSSendInterval();
				sms.SmsValidateFlag = ct.getSMSSmsValidateFlag().byteValue();
				sms.SmsStartFlag = ct.getSMSSmsStartFlag();
				sms.SmsEndFlag = ct.getSMSSmsEndFlag();
				sms.ExtSmsVar = ct.getSMSExtSmsVar();
				realFee = realFee + toInt(ct.getSMSSmsFeeCode());
				smsList.add(sms);
			} else if (ct.getFeeBigType() == ChannelBigType.WAP) {
				// WAP类
				if (ct.getEnable() == 0) {
					continue;
				}
				wap = new ChannelWAP();
				wap.FeeType = ct.getWAPFeeType();
				wap.ChannelID = channelID;
				wap.WapFeeUrl = ct.getWAPWapFeeURL();
				wap.FeeTipInfo = ct.getWAPFeeTipInfo();
				wap.ValidateStep = ct.getWAPValidateStep().byteValue();
				wap.ValidateFindKeys = ct.getWAPValidateFindKeys();
				wap.ValidateEndKey = ct.getWAPValidateEndKey();
				wap.SendCnt = ct.getWAPSendCnt();
				wap.SendInterval = ct.getWAPSendInterval();
				wap.FeeOKFlag = ct.getWAPFeeOKFlag();
				wap.FeeStep = ParseFetch.analyse(ct.getWAPFetchStrs());
				wap.ExtWapVar = ct.getWAPExtWapVar();
				realFee = realFee
						+ (ct.getWAPFeeCode() == null ? 0 : ct.getWAPFeeCode());
				wapList.add(wap);
			} else if (ct.getFeeBigType() == ChannelBigType.IVR) {
				// 拨打类
				if (ct.getEnable() == 0) {
					continue;
				}
				ivr = new ChannelIVR();
				ivr.FeeType = ct.getIVRFeeType();
				ivr.ChannelID = channelID;
				ivr.IvrFeeTel = ct.getIVRIvrFeeTel();
				ivr.FeeTipInfo = ct.getIVRFeeTipInfo();
				ivr.KeySeries = ct.getIVRKeySeries();
				ivr.SendCnt = ct.getIVRFeeMinTimeLen()
						+ RandomUtils.nextInt(10) + ct.getIVRStartFeeTimeLen(); // 计算发送时长
				ivr.SendInterval = ct.getIVRSendInterval();
				ivr.ExtIvrVar = ct.getIVRExtIvrVar();
				realFee = realFee
						+ (ct.getIVRFeeCode() == null ? 0 : ct.getIVRFeeCode());
				ivrList.add(ivr);
			} else if (ct.getFeeBigType() == ChannelBigType.SMSCLOSE) {
				if (ct.getEnable() == 0) {
					return null;
				}
				smsCloseCt = ct;
			}
		}
		res.ThisFee = realFee;
		if (smsList != null && smsList.size() > 0 && smsCloseCt != null) {
			res.sms = smsList.toArray(res.sms);
		} else {
			res.sms = new ChannelSMS[0];
		}
		if (wapList != null && wapList.size() > 0 && smsCloseCt != null) {
			res.wap = wapList.toArray(res.wap);
		} else {
			res.wap = new ChannelWAP[0];
		}
		if (ivrList != null && ivrList.size() > 0 && smsCloseCt != null) {
			res.ivr = ivrList.toArray(res.ivr);
		} else {
			res.ivr = new ChannelIVR[0];
		}
		if (smsCloseCt != null) {
			res.SmsCloseMt = smsCloseCt.getSmsCloseMt().byteValue();
			res.SmsCloseTime = smsCloseCt.getSmsCloseTime();
			res.SmsCloseSpNumber = smsCloseCt.getSmsCloseSpNumber();
			res.SmsOpenSpNumber = smsCloseCt.getSmsOpenSpNumber();
			res.SmsCloseKeyword = smsCloseCt.getSmsCloseKeyword();
			res.ExtRespVar = smsCloseCt.getExtRespVar();
		} else {
			res.SmsCloseMt = Constants.CloseMt.NeedClostMt;
			res.SmsCloseTime = Constants.CloseMt.CloseMtTimeLen;
			res.SmsCloseSpNumber = "";
			res.SmsOpenSpNumber = "";
			res.SmsCloseKeyword = "";
			res.ExtRespVar = "";
		}
		return res;

	}

	/**
	 * 根据num获取字符串str的值，如获取"0010"第二位，则返回1. 即 getBitValue("0010",2)=1; 返回0 or 1
	 * 
	 * @param num
	 *            指定位数
	 * @param str
	 *            Policy字符串
	 * @return
	 */
	public static int getBitValue(int num, String feePolicy, boolean isBelongU6) {
		try {
			String str = feePolicy;
			// 如果获取位，小于零，则设置第一位。
			if (num <= 0) {
				num = 1;
			}
			if (null == str || "".equals(str) || str.length() < num) {
				return 0;
			} else {
				char strnum = str.charAt(str.length() - num);

				try {
					if (!isBelongU6) {// 如果不是自有CP
						if (num == 1 || num == 2) {// 第一位和第二位都设置为0
							return 0;
						}
					}
					return Integer.parseInt(strnum + "");
				} catch (Exception e) {
					return 0;
				}
			}
		} catch (Exception e) {
			return 0;
		}
	}

	/**
	 * 将字符串转换为整形
	 * 
	 * @param str
	 * @return
	 */
	private static int toInt(String str) {
		if (null == str || "".equals(str)) {
			return 0;
		}
		try {
			return Integer.parseInt(str);
		} catch (Exception e) {
			return 0;
		}
	}

	public static void main(String[] args) {
		System.out.println(getBitValue(8, "1000030", true));
	}
}
